package cn.iocoder.yudao.module.system.service.expert;

import cn.iocoder.yudao.framework.common.enums.YesOrNoEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;

import java.util.*;

import cn.iocoder.yudao.module.system.controller.admin.expert.vo.*;
import cn.iocoder.yudao.module.system.dal.dataobject.expert.ExpertDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.system.dal.mysql.expert.ExpertMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;

/**
 * 专家 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class ExpertServiceImpl implements ExpertService {

    @Resource
    private ExpertMapper expertMapper;

    @Override
    public Long createExpert(ExpertSaveReqVO createReqVO) {
        // 插入
        ExpertDO expert = BeanUtils.toBean(createReqVO, ExpertDO.class);
        expertMapper.insert(expert);
        // 返回
        return expert.getId();
    }

    @Override
    public void updateExpert(ExpertSaveReqVO updateReqVO) {
        // 校验存在
        validateExpertExists(updateReqVO.getId());
        // 更新
        ExpertDO updateObj = BeanUtils.toBean(updateReqVO, ExpertDO.class);
        expertMapper.updateById(updateObj);
    }

    @Override
    public void deleteExpert(Long id) {
        // 校验存在
        validateExpertExists(id);
        // 删除
        expertMapper.deleteById(id);
    }

    private void validateExpertExists(Long id) {
        if (expertMapper.selectById(id) == null) {
            throw exception(EXPERT_NOT_EXISTS);
        }
    }

    @Override
    public ExpertDO getExpert(Long id) {
        if (Objects.isNull(id)) {
            return null;
        }
        return expertMapper.selectById(id);
    }

    @Override
    public ExpertDO getExpertByName(String name) {
        return expertMapper.selectOne(new LambdaQueryWrapper<ExpertDO>().eq(ExpertDO::getName, name));
    }

    @Override
    public PageResult<ExpertDO> getExpertPage(ExpertPageReqVO pageReqVO) {
        return expertMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ExpertDO> selectByExpertTypes(List<Integer> expertTypes) {
        if (CollectionUtils.isEmpty(expertTypes)) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<ExpertDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(ExpertDO::getType, expertTypes)
                .eq(ExpertDO::getDeleted, YesOrNoEnum.NO.getCode())
                .orderByDesc(ExpertDO::getLevel);
        return expertMapper.selectList(lambdaQueryWrapper);
    }

    @Override
    public ExpertDO getUseMinimumPointsExpert() {
        LambdaQueryWrapper<ExpertDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ExpertDO::getDeleted, YesOrNoEnum.NO.getCode())
                .orderByAsc(ExpertDO::getPoints)
                .orderByAsc(ExpertDO::getId)
                .last("limit 1");
        return expertMapper.selectOne(lambdaQueryWrapper);
    }

    @Override
    public ExpertDO getUseMaximumPointsExpert() {
        LambdaQueryWrapper<ExpertDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ExpertDO::getDeleted, YesOrNoEnum.NO.getCode())
                .orderByDesc(ExpertDO::getPoints)
                .orderByDesc(ExpertDO::getId)
                .last("limit 1");
        return expertMapper.selectOne(lambdaQueryWrapper);
    }

}